﻿using HtmlAgilityPack;
using MusicExplorer.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Fizzler.Systems.HtmlAgilityPack;
using MusicExplorer.Repository.Interfaces;

namespace MusicExplorer.Repository
{
    public sealed class WorldOfHouseRepository : RepositoryBase, ITracksByGenre
    {
        private const string m_websiteUrl = @"http://www.worldofhouse.es";

        private readonly Dictionary<SearchUrl, string> m_urls;

        public WorldOfHouseRepository()
        {
            m_urls = new Dictionary<SearchUrl, string>();
            m_urls[SearchUrl.SearchArtist] = m_websiteUrl + @"/search/{0}/page/{1}/tab/producers";
            m_urls[SearchUrl.GetGenres] = m_websiteUrl + @"/contact";
            m_urls[SearchUrl.SearchTracksFromGenre] = m_websiteUrl + @"/genre/{0}/page/{1}/tab/filter_paginator";
        }

        public async Task<List<Track>> GetTracksByGenre(string genreId, int page)
        {
            var source = await RepositoryHelper.GetOnlineSourceAsync(string.Format(m_urls[SearchUrl.SearchTracksFromGenre],
                genreId, page));
            return await DecodeTracks(source);
        }

        public override async Task<List<Track>> DecodeTracks(string source)
        {
            return await Task<List<Track>>.Factory.StartNew(() =>
            {
                var document = new HtmlDocument();
                document.LoadHtml(source);
                var page = document.DocumentNode;

                var tracks = new List<Track>();
                var listNode = page.QuerySelector("#pagi_main_filter_paginator");
                foreach(var trackNode in listNode.ChildNodes.Where(n => n.Name == "div"))
                {
                    var track = new Track();
                    var link = trackNode.QuerySelector("a");
                    track.Id = link.Attributes["href"].Value.Split('/')[1];
                    track.Name = link.InnerText;
                    track.Mp3 = string.Format(@"{0}/mp3/streaming/{1}.mp3",
                        m_websiteUrl, track.Id);
                    track.Url = link.Attributes["href"].Value;
                    var img = trackNode.QuerySelector(".image > img");
                    var data = img.Attributes["data-original"].Value;
                    if (data == @"/images/default_cover.jpg")
                    {
                        track.SmallArtwork = string.Format(@"{0}{1}", m_websiteUrl, data);
                    }
                    else
                    {
                        track.SmallArtwork = data;
                    }
                    track.BigArtwork = track.SmallArtwork.Replace("80_80", "296_296");
                    tracks.Add(track);
                }
                return tracks;
            });
        }

        public async Task<List<Genre>> GetGenres()
        {
            var source = await RepositoryHelper.GetOnlineSourceAsync(m_urls[SearchUrl.GetGenres]);
            return await DecodeGenres(source);
        }

        public async Task<List<Genre>> DecodeGenres(string source)
        {
            return await Task<List<Genre>>.Factory.StartNew(() =>
                {
                    var document = new HtmlDocument();
                    document.LoadHtml(source);
                    var page = document.DocumentNode;

                    var genres = new List<Genre>();

                    // 1. Chargement des genres généraux
                    var menuNode = page.QuerySelector("#genre_menu");
                    var allGenresNodes = menuNode.QuerySelectorAll("[id^='genre_menu_']");
                    foreach(var genreNode in allGenresNodes)
                    {
                        var genre = new Genre();
                        var linkNode = genreNode.QuerySelector("a");
                        var classNode = genreNode.QuerySelector(".genre_menu_item");
                        genre.Id = linkNode.Attributes["href"].Value.Split('/')[1];
                        genre.Name = classNode.InnerText;
                        genres.Add(genre);
                    }

                    // 2. Chargement des sous genres
                    var subMenuNode = page.QuerySelector("#genres_menu_list");
                    var subMenuGroupNodes = subMenuNode.QuerySelectorAll("td");
                    foreach (var subMenuGroupNode in subMenuGroupNodes)
                    {
                        foreach(var subGenreNode in subMenuGroupNode.ChildNodes.Where(n => n.Name == "div"))
                        {
                            var genre = new Genre();
                            var linkNode = subGenreNode.QuerySelector("a");
                            genre.Id = linkNode.Attributes["href"].Value.Split('/')[1];
                            genre.Name = linkNode.InnerText;
                            genres.Add(genre);
                        }
                    }

                    return genres;
                });
        }

        //public async Task<List<Artist>> SearchArtists(string pattern, int page)
        //{
        //    pattern = pattern.Replace(' ', '+');
        //    var source = await RepositoryHelper.GetOnlineSource(string.Format(m_urls[SearchUrl.SearchArtist],
        //        pattern, page));
        //    return await DecodeArtists(source);
        //}

        //internal async Task<List<Artist>> DecodeArtists(string source)
        //{
        //    return await Task<List<Artist>>.Factory.StartNew(() =>
        //        {
        //            var document = new HtmlDocument();
        //            document.LoadHtml(source);
        //            var page = document.DocumentNode;

        //            var artists = new List<Artist>();
        //            foreach (var node in page.QuerySelector("#pagi_main_producers").ChildNodes)
        //            {
        //                if (node.Name == "script") continue;

        //                var link = node.QuerySelector("a");
        //                var artist = new Artist();
        //                artist.Id = link.Attributes["href"].Value.Split('/')[1];
        //                artist.Name = link.InnerText;
        //                artists.Add(artist);
        //            }

        //            return artists;
        //        });
        //}
    }
}
